﻿namespace MediaInfoLib
{
    using System;
    using System.Runtime.InteropServices;

    public class MediaInfo : IDisposable
    {
        private static MediaInfoLib.MediaInfo _instance;
        private IntPtr Handle;

        private MediaInfo()
        {
            try
            {
                this.Handle = MediaInfo_New();
            }
            catch
            {
            }
        }

        public void Close()
        {
            MediaInfo_Close(this.Handle);
        }

        public void Dispose()
        {
            if (!(this.Handle == IntPtr.Zero))
            {
                MediaInfo_Delete(this.Handle);
                this.Handle = IntPtr.Zero;
            }
        }

        ~MediaInfo()
        {
            try
            {
                if (this.Handle != IntPtr.Zero)
                {
                    MediaInfo_Delete(this.Handle);
                    this.Handle = IntPtr.Zero;
                }
            }
            catch
            {
            }
        }

        public string Get(MediaInfoLib.StreamKind StreamKind, uint StreamNumber, string Parameter)
        {
            return this.Get(StreamKind, StreamNumber, Parameter, MediaInfoLib.InfoKind.Text, MediaInfoLib.InfoKind.Name);
        }

        public string Get(MediaInfoLib.StreamKind StreamKind, uint StreamNumber, string Parameter, MediaInfoLib.InfoKind KindOfInfo)
        {
            return this.Get(StreamKind, StreamNumber, Parameter, KindOfInfo, MediaInfoLib.InfoKind.Name);
        }

        private string Get(MediaInfoLib.StreamKind StreamKind, uint StreamNumber, string Parameter, MediaInfoLib.InfoKind KindOfInfo, MediaInfoLib.InfoKind KindOfSearch)
        {
            return Marshal.PtrToStringUni(MediaInfo_Get(this.Handle, StreamKind, StreamNumber, Parameter, KindOfInfo, KindOfSearch));
        }

        public string getAR()
        {
            return this.Get(MediaInfoLib.StreamKind.Video, 0, "AspectRatio");
        }

        public string getAudioBitrate()
        {
            return this.Get(MediaInfoLib.StreamKind.Audio, 0, "BitRate");
        }

        public string getAudioCodec()
        {
            return this.Get(MediaInfoLib.StreamKind.Audio, 0, "Codec");
        }

        public string getAudioCount()
        {
            return this.Get(MediaInfoLib.StreamKind.Audio, 0, "StreamCount");
        }

        public string getFPS()
        {
            return this.Get(MediaInfoLib.StreamKind.Video, 0, "FrameRate");
        }

        public string getHeight()
        {
            return this.Get(MediaInfoLib.StreamKind.Video, 0, "Height");
        }

        public static MediaInfoLib.MediaInfo GetInstance()
        {
            if (_instance == null)
            {
                return (_instance = new MediaInfoLib.MediaInfo());
            }
            return _instance;
        }

        public string getNoChannels()
        {
            return this.getNoChannels(0);
        }

        public string getNoChannels(int stream)
        {
            return this.Get(MediaInfoLib.StreamKind.Audio, (uint) stream, "Channel(s)");
        }

        public string getPlaytime()
        {
            return this.Get(MediaInfoLib.StreamKind.Video, 0, "PlayTime");
        }

        public string getVidBitrate()
        {
            return this.Get(MediaInfoLib.StreamKind.Video, 0, "BitRate");
        }

        public string getVidCodec()
        {
            return this.Get(MediaInfoLib.StreamKind.Video, 0, "Codec");
        }

        public string getWidth()
        {
            return this.Get(MediaInfoLib.StreamKind.Video, 0, "Width");
        }

        [DllImport("MediaInfo.dll")]
        private static extern void MediaInfo_Close(IntPtr Handle);
        [DllImport("MediaInfo.dll")]
        private static extern void MediaInfo_Delete(IntPtr Handle);
        [DllImport("MediaInfo.dll")]
        private static extern IntPtr MediaInfo_Get(IntPtr Handle, [MarshalAs(UnmanagedType.U4)] MediaInfoLib.StreamKind StreamKind, uint StreamNumber, [MarshalAs(UnmanagedType.LPWStr)] string Parameter, [MarshalAs(UnmanagedType.U4)] MediaInfoLib.InfoKind KindOfInfo, [MarshalAs(UnmanagedType.U4)] MediaInfoLib.InfoKind KindOfSearch);
        [DllImport("MediaInfo.dll")]
        private static extern IntPtr MediaInfo_New();
        [DllImport("MediaInfo.dll")]
        private static extern int MediaInfo_Open(IntPtr Handle, [MarshalAs(UnmanagedType.LPWStr)] string FileName);
        public int Open(string FileName)
        {
            return MediaInfo_Open(this.Handle, FileName);
        }
    }
}

